using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace Krilib.Control
{
    /// <summary>
    /// eXtended draw String
    /// </summary>
    public class XString : ICloneable
    {
        public string Original { get; set; }

        public string HeaderText { get; set; }
        public string FooterText { get; set; }

        private Surface.MessageObject[] msgobjs = null;

        /// <summary>
        /// Get contain msgobjs.
        /// </summary>
        public Surface.MessageObject[] MessageObjects
        {
            get { return msgobjs; }
            set { msgobjs = value; }
        }

        /*
        private Size drawSize = new Size();
        /// <summary>
        /// Real draw size,if you get this prop , please exec Reflesh() before get.
        /// </summary>
        public Size DrawSize { get { return drawSize; } }

        private object rectlistLocker = new object();
        private Dictionary<Rectangle, MessageObject> rectlist = new Dictionary<Rectangle,MessageObject>();

        /// <summary>
        /// Lookup MsgObj by Rectangle(with using foreach?)
        /// </summary>
        public Dictionary<Rectangle, MessageObject> RectangleList
        {
            get
            {
                lock (rectlistLocker)
                    return rectlist;
            }
        }

        /// <summary>
        /// DrawMode flags
        /// </summary>        
        [Flags]
        public enum DrawMode
        {
            None = 0,
            SingleLine = 1
        }

        /// <summary>
        /// Recompute object position and drawing state
        /// </summary>
        /// <param name="width">suppose width</param>
        /// <param name="dmode">draw mode</param>
        public void Measure(int width, int initHeight, DrawMode dmode)
        {
            Rectangle destrect = new Rectangle(0, 0, width, 1);
            lock (rectlistLocker)
            {
                rectlist.Clear();
                destrect.Width -= Bridge.Config.DrawMargin * 2;
                foreach (MessageObject obj in msgobjs)
                {
                    //using "yield return"
                    IEnumerator<Rectangle> enumerator = obj.Measure(destrect, initHeight).GetEnumerator();
                    do
                    {
                        if (enumerator.Current != default(Rectangle))
                            rectlist.Add(enumerator.Current, obj);
                    } while (enumerator.MoveNext());
                    destrect = obj.MeasureEndRect;
                }
            }
            drawSize = new Size(width, destrect.Bottom);
        }

        /// <summary>
        /// Draw Message Objects
        /// </summary>
        /// <param name="g">Graphics instance</param>
        /// <param name="r">destination rectangle</param>
        /// <param name="dmode">draw mode</param>
        public void Draw(Graphics g, Point p, DrawMode dmode)
        {
            foreach (MessageObject obj in msgobjs)
            {
                obj.Draw(g, p);
            }
        }

         * */

        public void Release()
        {
            foreach (var m in msgobjs)
            {
                m.Release();
            }
        }

        public object Clone()
        {
            var ret = new XString();
            if (this.Original != null)
                ret.Original = (String)this.Original.Clone();
            if (this.HeaderText != null)
                ret.HeaderText = (String)this.HeaderText.Clone();
            if (this.FooterText != null)
                ret.FooterText = (String)this.FooterText.Clone();
            if (this.MessageObjects != null)
                ret.MessageObjects = (Surface.MessageObject[])this.MessageObjects.Clone();
            return ret;
        }
    }
}
